package com.dandelion.api.service;

import com.dandelion.common.domain.CategoryServiceRelationVO;
import com.dandelion.common.domain.CategoryVO;
import com.dandelion.common.service.DictDataService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class InMemoryDictDataScheduledService {
    private static final Logger logger = LoggerFactory.getLogger(InMemoryDictDataScheduledService.class);

    @Autowired
    private DictDataService dictDataService;

    private volatile List<CategoryServiceRelationVO> topCatAndSvrList;
    private volatile LinkedHashMap<String, CategoryVO> categoryMap;

//    public InMemoryDictDataScheduledService() {
//        logger.info("Loading dict data schedule started");
//        scheduleTopCatAndSvrRelationshipList();
//
//        logger.info("Loading dict data schedule finished");
//    }

//    @Scheduled(fixedDelay = 1000L)
//    public void schedule() {
//        logger.info("Loading dict data schedule started");
//        scheduleTopCatAndSvrRelationshipList();
//
//        logger.info("Loading dict data schedule finished");
//    }

    public void reload() {
        scheduleAll();
    }

    @PostConstruct
    private void scheduleAll() {
        scheduleTopCatAndSvrRelationshipList();
        scheduleCategoryList();
    }

    private void scheduleTopCatAndSvrRelationshipList() {
        try {
            this.topCatAndSvrList = dictDataService.getTopCatAndServices();
        } catch (Exception e) {
            logger.error("Load relationship list to memory error", e);
        }
    }

    private void scheduleCategoryList() {
        try {
            List<CategoryVO> voList = dictDataService.getAllCategoryTee();
            if (CollectionUtils.isEmpty(voList)) {
                return;
            }
            LinkedHashMap map = new LinkedHashMap(voList.size());
            for (CategoryVO cat : voList) {
                map.put(cat.getId(), cat);

                List<CategoryVO> children = getCategoryByParentIdInternal(voList, cat.getId());
                cat.setChildren(children);
            }

            this.categoryMap = map;
        } catch (Exception e) {
            logger.error("Load relationship list to memory error", e);
        }
    }

    public List<CategoryServiceRelationVO> getTopCatAndSvrList() {
        return topCatAndSvrList;
    }

    public Map<String, CategoryVO> getCategoryMap() {
        return categoryMap;
    }

    public List<CategoryVO> getCategoryByParentId(String parentId) {
        Map<String, CategoryVO> map = this.categoryMap;
        if (!"0".equals(parentId)) {
            CategoryVO cat = map != null ? map.get(parentId) : null;
            return cat == null ? Lists.newArrayList() : cat.getChildren();
        } else {
            return map.entrySet()
                    .stream()
                    .map(e -> e.getValue())
                    .filter(v -> parentId.equals(v.getParentId()))
                    .collect(Collectors.toList());
        }
    }

    private static List<CategoryVO> getCategoryByParentIdInternal(List<CategoryVO> all, String parentId) {
        return all
                .stream()
                .filter(cat -> parentId.equals(cat.getParentId()))
                .collect(Collectors.toList());
    }

}
